﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Security.Principal;
using System.Threading;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using WeBlog.Interfaces;
using WeBlog.Models;
using WeBlog.Repositories;
using WeBlog.Services;

namespace WeBlog.Controllers
{
    [HandleErrorWithELMAH]
    public class ApplicationController : Controller
    {
        public IPrincipal Principal { get; set; }
        protected IUnitOfWork UnitOfWork { get; set; }
        public SiteConfiguration SiteConfiguration { get; set; }

        public ApplicationController( IUnitOfWork unitOfWork )
        {
            UnitOfWork = unitOfWork;
            SiteConfiguration = SiteManager.CurrentConfiguration;            

            if (System.Web.HttpContext.Current != null)
            {
                if (System.Web.HttpContext.Current.Session != null)
                {
                    if (System.Web.HttpContext.Current.Session["User"] != null)
                        CurrentUser = System.Web.HttpContext.Current.Session["User"] as User;
                }
            }
            
            if( CurrentUser == null )
                CurrentUser = new User { RoleFlag = RoleValues.Subscriber };            
            

            if (System.Web.HttpContext.Current != null)
            {
                if (System.Web.HttpContext.Current.User != null)
                {
                    Principal = System.Web.HttpContext.Current.User;
                }
            }
            else
            {
                if (Thread.CurrentPrincipal != null)
                    Principal = Thread.CurrentPrincipal;
            }

            if (Principal.Identity.IsAuthenticated)
            {                
                Principal = new GenericPrincipal(Principal.Identity, CurrentUser.GetRoles() );

                if (System.Web.HttpContext.Current != null)
                    System.Web.HttpContext.Current.User = Principal;
                else
                    Thread.CurrentPrincipal = Principal;
            }   
        }              
        
        protected internal void LogOn(User user, bool rememberMe)
        {
            var principal = new GenericPrincipal(new GenericIdentity(user.Email), user.GetRoles());

            if (System.Web.HttpContext.Current != null)
            {
                DateTime expires = DateTime.Now.AddDays(20);
                var ticket = new FormsAuthenticationTicket(
                    1,                        //version
                    user.Email,               //user name
                    DateTime.Now,             //creation
                    expires,                  //Expiration
                    rememberMe,               //Persistent
                    String.Join(",", user.GetRoles())
                );
                string encryptedTicket = FormsAuthentication.Encrypt(ticket);
                var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
                if (ticket.IsPersistent) authCookie.Expires = expires;
                Response.Cookies.Add(authCookie);
                //set the session variables
                Session["Principal"] = principal;
                Session["User"] = user;
            }
            else
            {
                Thread.CurrentPrincipal = principal;
            }
        }
        
        public User CurrentUser
        {
            get;
            set;             
        }     
       
        public ActionResult NotFound()
        {
            return View("NotFound");
        }

        public ActionResult PermissionDenied()
        {
            return View("PermissionDenied");
        }

        protected override void OnException(ExceptionContext filterContext)
        {            
            if (filterContext.Exception is NotFoundException)
            {
                filterContext.Result = NotFound();
                filterContext.ExceptionHandled = true;
                return;
            }

            base.OnException(filterContext);
        }
    }
}
